package vin.pth.authorization.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import vin.pth.authorization.exception.AuthorizationException;
import vin.pth.authorization.handler.AuthorizationHandler;
import vin.pth.authorization.service.AuthorizationUserService;
import vin.pth.base.pojo.Authentication;

/**
 * 认证Bean注册器.
 *
 * @author cocoon
 */
@Slf4j
@Configuration
@ConditionalOnProperty(name = "cocoon-security.authorization.enable", matchIfMissing = true)
public class AuthorizationDefaultBeanRegister {

  @Resource
  private AuthorizationUserService authorizationUserService;


  /**
   * 默认的认证处理器，定义了默认的认证通过和失败的行为.
   *
   * @return AuthorizationHandler
   */
  @ConditionalOnMissingBean(AuthorizationHandler.class)
  @Bean
  public AuthorizationHandler authorizationHandler() {
    return new AuthorizationHandler() {

      @SneakyThrows
      @Override
      public void failureHandler(HttpServletRequest request, HttpServletResponse response,
          AuthorizationException e) {
        log.warn("默认的用户授权处理器，请自行实现AuthorizationHandler");
        var map = new HashMap<String, String>(8);
        map.put("code", "1");
        map.put("message", e.getMessage());
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getWriter().write(new ObjectMapper().writeValueAsString(map));
      }

      @SneakyThrows
      @Override
      public void successHandle(HttpServletRequest request, HttpServletResponse response,
          Authentication authenticate) {
        log.warn("默认的用户授权处理器，请自行实现AuthorizationHandler");
        var map = new HashMap<String, String>(8);
        map.put("token", authorizationUserService.generateToken(authenticate.getUserDetails()));
        response.getWriter().write(new ObjectMapper().writeValueAsString(map));
      }
    };
  }

}
